package de.hwrBerlin.dataMining.view;

import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.TabItem;

import de.hwrBerlin.dataMining.constants.ConfigConstants;
import de.hwrBerlin.dataMining.constants.Images;
import de.hwrBerlin.dataMining.constants.UIConstants;
import de.hwrBerlin.dataMining.controller.Controller;
import de.hwrBerlin.dataMining.controller.observer.Observer;
import de.hwrBerlin.dataMining.dataStructure.TableData;
import de.hwrBerlin.dataMining.dataStructure.TreeNode;
import de.hwrBerlin.dataMining.view.dialog.AddAttributeDialog;
import de.hwrBerlin.dataMining.view.dialog.AddLineDialog;
import de.hwrBerlin.dataMining.view.dialog.DeleteAttributeDialog;
import de.hwrBerlin.dataMining.view.dialog.EditAttributeDialog;
import de.hwrBerlin.dataMining.view.dialog.EditLineDialog;
import de.hwrBerlin.dataMining.view.widgets.combo.ExtendedComboBox;
import de.hwrBerlin.dataMining.view.widgets.table.ExtendedTable;
import de.hwrBerlin.tools.logger.LogLevel;
import de.hwrBerlin.tools.logger.Logger;

public class TableView extends Composite implements Observer {
    
    private ExtendedTable _table;
    private Controller _controller;

    private Button _newTable;
    private Button _editAttribute;
    private Button _deleteAttribute;
    private Button _addAttribute;
    private Button _editLine;
    private Button _deleteLine;
    private Button _addLine;
    private ExtendedComboBox _selectedAttribut;
    
    
    
    public TableView(Composite pParent, int pStyle, TabItem pTabItem, final Controller pController) {
        super(pParent, pStyle);
        
        _controller = pController;
        
        _controller.addObserverToModel(this);
        final TableView tmpThis = this;
        this.addDisposeListener(new DisposeListener() {
            @Override
            public void widgetDisposed(DisposeEvent pArg0) {
                _controller.removeObserverToModel(tmpThis);
            }
        });
        
        GridLayout layout = new GridLayout(1, false);
        layout.marginWidth = 5;
        layout.marginHeight = 5;
        setLayout(layout);
        
        Composite optionComposite = new Composite(this, SWT.BORDER);
        optionComposite.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
        FillLayout fillLayout = new FillLayout(SWT.HORIZONTAL);
        fillLayout.spacing = 2;
        fillLayout.marginWidth = 1;
        fillLayout.marginHeight = 1;
        optionComposite.setLayout(fillLayout);
        
        Composite buttonComposite = new Composite(optionComposite, SWT.NONE);
        buttonComposite.setLayout(new GridLayout(12, false));
        
        _newTable = new Button(buttonComposite, SWT.PUSH);
        _newTable.setImage(new Image(getDisplay(), Images.NEW_TABLE));
        _newTable.setToolTipText(UIConstants.NEW_TABLE_TOOL_TIP);
        _newTable.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent pE) {
                _controller.loadTable(new TableData());
            }
        });
        _newTable.setEnabled(true);
        
        new Label(buttonComposite, SWT.NONE).setText("");
        
        _addLine = new Button(buttonComposite, SWT.PUSH);
        _addLine.setImage(new Image(getDisplay(), Images.ADD_COLUMN));
        _addLine.setToolTipText(UIConstants.ADD_ROW_TOOL_TIP);
        _addLine.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent pE) {
                new AddLineDialog(getShell(), SWT.NONE).open(_controller);
            }
        });
        _addLine.setEnabled(false);
        
        _deleteLine = new Button(buttonComposite, SWT.PUSH);
        _deleteLine.setImage(new Image(getDisplay(), Images.REMOVE_COLUMN));
        _deleteLine.setToolTipText(UIConstants.REMOVE_ROW_TOOL_TIP);
        _deleteLine.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent pE) {
                MessageBox deleteBox = new MessageBox(getShell(), SWT.ICON_WARNING | SWT.CANCEL | SWT.OK);
                deleteBox.setText(UIConstants.REMOVE_ROW_TOOL_TIP);
                deleteBox.setMessage(UIConstants.REMOVE_ROW_MESSAGE + "\n" + _table.getSelection().toString());
                if (deleteBox.open() == SWT.OK) {
                    _controller.removeLine(_table.getTable().getSelectionIndices()[0]);
                    _editLine.setEnabled(false);
                    _deleteLine.setEnabled(false);
                }
            }
        });
        _deleteLine.setEnabled(false);
        
        _editLine = new Button(buttonComposite, SWT.PUSH);
        _editLine.setImage(new Image(getDisplay(), Images.EDIT_COLUMN));
        _editLine.setToolTipText(UIConstants.EDIT_ROW_TOOL_TIP);
        _editLine.addSelectionListener(new SelectionAdapter() {
            @SuppressWarnings("unchecked")
            @Override
            public void widgetSelected(SelectionEvent pE) {
                new EditLineDialog(getShell(), SWT.NONE).open(_controller, (List<String>) _table.getSelection(), _table.getTable().getSelectionIndices()[0] + 1);
            }
        });
        _editLine.setEnabled(false);
        
        new Label(buttonComposite, SWT.NONE).setText("");
        
        _addAttribute = new Button(buttonComposite, SWT.PUSH);
        _addAttribute.setImage(new Image(getDisplay(), Images.ADD_ROW));
        _addAttribute.setToolTipText(UIConstants.ADD_COLUMN_TOOL_TIP);
        _addAttribute.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent pE) {
                new AddAttributeDialog(getShell(), SWT.NONE).open(_controller);
            }
        });
        _addAttribute.setEnabled(false);
        
        _deleteAttribute = new Button(buttonComposite, SWT.PUSH);
        _deleteAttribute.setImage(new Image(getDisplay(), Images.REMOVE_ROW));
        _deleteAttribute.setToolTipText(UIConstants.REMOVE_COLUMN_TOOL_TIP);
        _deleteAttribute.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent pE) {
                new DeleteAttributeDialog(getShell(), SWT.NONE).open(_controller);
            }
        });
        _deleteAttribute.setEnabled(false);
        
        _editAttribute = new Button(buttonComposite, SWT.PUSH);
        _editAttribute.setImage(new Image(getDisplay(), Images.EDIT_ROW));
        _editAttribute.setToolTipText(UIConstants.EDIT_COLUMN_TOOL_TIP);
        _editAttribute.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent pE) {
                new EditAttributeDialog(getShell(), SWT.NONE).open(_controller);
            }
        });
        _editAttribute.setEnabled(false);
        
        new Label(buttonComposite, SWT.NONE).setText("");
        
        Label selectedAttributLabel = new Label(buttonComposite, SWT.NONE);
        selectedAttributLabel.setText(UIConstants.TARGET_ATTRIBUTE + ":");
        selectedAttributLabel.setToolTipText(UIConstants.TARGET_ATTRIBUTE_TOOLTIP);
        
        _selectedAttribut = new ExtendedComboBox(buttonComposite, SWT.READ_ONLY, false);
        _selectedAttribut.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent pE) {
                pController.setTargetAttribute((String) _selectedAttribut.getSelection());
            }
        });
        _selectedAttribut.getCombo().setEnabled(false);
        
        _table = new ExtendedTable(this, SWT.BORDER | SWT.FULL_SELECTION, new ListTableShower());
        _table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        _table.getTable().setHeaderVisible(true);
        _table.getTable().setLinesVisible(true);
        _table.getTable().addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent pE) {
                if (_table.getSelection() != null) {
                    _editLine.setEnabled(true);
                    _deleteLine.setEnabled(true);
                }
                else {
                    _editLine.setEnabled(false);
                    _deleteLine.setEnabled(false);
                }
            }
        });

        updateTreeButtonsEnabled(_controller.getModel().getTable());
        
        pTabItem.setControl(this);
    }
    
    
    
    private void updateTreeButtonsEnabled(TableData pTableData){
        Logger.log(LogLevel.DEBUG, "update Table-Buttons");
        if(pTableData == null){
            _addLine.setEnabled(false);
            _addAttribute.setEnabled(false);
            _editAttribute.setEnabled(false);
            _deleteAttribute.setEnabled(false);
            _selectedAttribut.getCombo().setEnabled(false);
        }
        else{
            _addLine.setEnabled(pTableData.getRowCount()-1 < ConfigConstants.MAX_ROWS && pTableData.getColumnCount() > 0);
            _addAttribute.setEnabled(pTableData.getColumnCount() < ConfigConstants.MAX_ATTRIBUTES);
            _editAttribute.setEnabled(pTableData.getColumnCount() > 0);
            _deleteAttribute.setEnabled(pTableData.getColumnCount() > 0);
            _selectedAttribut.getCombo().setEnabled(pTableData.getColumnCount() > 0);
        }
    }
    
    
    
    @Override
    public void updateAllTable(TableData pTableData) {
        _table.setColumns(pTableData.getAttributNames());
        int selectedColumn = -1;
        for (int i = 0; pTableData.getAttributNames().length > i; i++) {
            if (pTableData.getAttributNames()[i].equals(pTableData.getSelectedAttribute())) {
                selectedColumn = i;
                break;
            }
        }
        _table.setInput(pTableData.getRows(), selectedColumn);
        _selectedAttribut.setInput(pTableData.getAttributNames());
        _selectedAttribut.setSetlection(pTableData.getSelectedAttribute());

        updateTreeButtonsEnabled(pTableData);
    }
    
    
    
    @Override
    public void updateTree(TreeNode pTree) {
    }
    
    
    
    @Override
    public void updateAllInteractiveTree(TreeNode pTree) {
    }
    
    
    
    @Override
    public void updateAllAutomaticTree(TreeNode pTree) {
    }
    
    
    
    public Button getEditAttributeButton() {
        return _editAttribute;
    }
    
    
    
    public Button getDeleteAttributeButton() {
        return _deleteAttribute;
    }
    
    
    
    public Button getAddAttributeButton() {
        return _addAttribute;
    }
    
    
    
    public Button getEditLineButton() {
        return _editLine;
    }
    
    
    
    public Button getDeleteLineButton() {
        return _deleteLine;
    }
    
    
    
    public Button getAddLineButton() {
        return _addLine;
    }
    
}
